Conversation
|
Thank you for your contribution to TestCafe. When a member of the TestCafe team becomes available, they will review this PR. |
Add a browser-level CDP client to the Chrome BrowserClient and use it to create and dispose browser contexts (Target.createBrowserContext) with one page target each. A NativeAutomationIsolatedWindow attaches to such a target with the page-level CDP setup only, without the request pipeline and proxy hooks the main window uses. The main window's targetCreated handler now ignores targets from other browser contexts, so an isolated tab does not get treated as a child window of the test page. The browser-level connection is cached as a promise and forgotten on disconnect and on close; a failed target creation disposes the context it was created in so nothing leaks.
t.openIsolatedSession() opens a second browser session in an isolated CDP browser context (own cookies, storage, cache and HTTP auth) and resolves to an IsolatedTestController. Multi-user scenarios such as a video call between two accounts can run inside one test in one browser instead of two concurrent tests or two browsers. The controller exposes the TestController action, assertion, cookie, screenshot, window and role API and executes commands against the isolated tab directly over CDP (Input, Runtime, Page, Network, Storage). Selectors and client functions are compiled with the regular builders and evaluated in the isolated page. t2.run(fn) executes a callback in which Selector, ClientFunction and t.expect resolve against the isolated tab, so page objects written for t work unchanged. Isolated sessions are disposed when the test finishes, before the before-done hooks. Opening one without native automation throws the coded error E103.
Add the isolated-sessions functional suite (own gulp task, excluded from the screenshot glob) covering isolation of cookies and storage, actions, selectors and assertions, t2.run, iframes, roles, HTTP auth, file upload, screenshots and window management. Add a server test for context creation and disposal in the CDP client, TypeScript definition checks for the new API, the E103 formatting test and the openIsolatedSession exception in the TestController events test, since opening a session is a task and not a logged command.
…caretPos in contenteditable dispatchEvent forwarded relatedTarget inside the plain options object, so an element passed as relatedTarget never reached the event as a node; it is now resolved like the target and passed by object id. typeText with caretPos placed the caret only in input and textarea elements; in a contenteditable element the caret now moves to the requested offset.
sam-yh
requested a deployment
to
authentication
September 28, 2026 09:27 — with
GitHub Actions
Waiting
…shes Every element lookup created a Runtime remote object without an object group and nothing released it, so handles lived until the isolated tab closed and elements the page had removed stayed in memory; thrown exceptions were retained too. Lookups, the scroll document and evaluateExpression now use the isolated-command group, released with Runtime.releaseObjectGroup when the last t2 command in flight finishes. The iframe element entered with switchToIframe is copied into the isolated-frames group and released on switchToMainWindow or navigateTo.
sam-yh
requested a deployment
to
authentication
September 28, 2026 11:13 — with
GitHub Actions
Waiting
This branch is waiting to be deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
t.openIsolatedSession(). It creates a Chromium browser context over CDP (Target.createBrowserContext) with its own cookies, storage, cache and HTTP auth, opens a page target in it and resolves to anIsolatedTestControllerfor that page. One test can then drive two users in one browser: doctor and patient in a video call, two editors of the same document, concurrent bookings.Related: #5291 (different roles in different windows, closed as not planned).
API
t2accepts CSS strings andSelectorobjects (including chains:withText,withExactText,withAttribute,nth,find,parent,child,sibling,nextSibling,prevSibling,filterVisible,filterHidden). Calls chain like ont, includingexpect. Sessions are disposed when the test ends.Methods on
t2Actions:
click,rightClick,doubleClick,hover,drag,dragToElement,typeText,pressKey,selectText,scroll,scrollBy,scrollIntoView,dispatchEvent,setFilesToUpload,clearUpload,wait,navigateTo.Other:
expect,eval,useRole,getCookies,setCookies,deleteCookies,takeScreenshot,takeElementScreenshot,switchToIframe,switchToMainWindow,maximizeWindow,resizeWindow,setWindowBounds,setHttpAuth,setPageLoadTimeout,run.Not on
t2:openWindowand the window switching methods,getCurrentCDPSession,setNativeDialogHandler,getNativeDialogHistory,getBrowserConsoleMessages,addRequestHooks,removeRequestHooks,request,debug,setTestSpeed,skipJsErrors,report,selectTextAreaContent,selectEditableContent,resizeWindowToFitDevice,customActions,ctx/fixtureCtx/browser/test/fixture.t2.run(fn)t2.runexecutesfnwith the isolated page as the target of everything that normally goes to the test page:tresolves tot2for the duration of the callback, sot.click(...),t.expect(...)and page objects written againsttact on the isolated page.SelectorandClientFunctioncalls made in the callback (property reads such assel.innerText,sel.exists, assertions on selector properties,ClientFunctioninvocations) execute in the isolated page. Routing is a stack, so nested calls for another session and the main page after the callback are unaffected.t:await t.click(a).typeText(b, 'x').runresolves, sot2.run(() => { t.click('#a'); })completes the click.tis restored. Assertions on selector properties throught2.expect(...)work outsiderunas well; only bareSelector/ClientFunctioncalls needrunto target the isolated page.t2(see above) are not available ontinside the callback either.Differences from
tselectorTimeoutand checks visibility, but the action itself is CDP input:typeTextusesInput.insertText(no per-character key events) and appends unlessreplaceorcaretPosis given;pressKeysends key events for single keys and modifier combinations.assertionTimeoutwith the same options as ont.dispatchEventbuilds the matching event class fromeventNameand its options; arelatedTargetoption given as a selector is resolved to an element.useRoleapplies the role's cookie snapshot; the role must have been initialized bytfirst, the isolated session cannot run the role's init function.alert,confirm,prompt) in the isolated page is dismissed (confirmreturns false,promptreturns null) and fails thet2command that raised it;beforeunloadis accepted. There is no dialog handler API ont2.navigateTothrows when Chromium reports a navigation error instead of continuing on the error page.setHttpAuthsets anAuthorizationheader on every request from the isolated page, including cross-origin ones.t2.evalandClientFunctionsupport serializable dependencies;ClientFunction(fn).with({ boundTestRun: t2 })targets the isolated page.Known limits
t.openIsolatedSession()in proxy mode throws E103.RequestLoggerorRequestMockfor the isolated page: it is not proxied.switchToIframe; same-origin iframes, nested ones and iframes picked bynthor attribute selectors are.Selector(() => ...)) and.filter(fn)are not supported; use CSS,withText,withAttributeor the other chain methods.t2.openIsolatedSession()) andopenWindowont2are not available.t.getBrowserConsoleMessagesequivalent.Implementation
src/browser/provider/built-in/dedicated/chrome/cdp-client/index.ts: browser-level CDP connection (cached promise, reset on disconnect, closed with the browser),createIsolatedContext/disposeIsolatedContext.src/browser/provider/built-in/dedicated/chrome/index.js:createIsolatedSession/disposeIsolatedSession/getBrowserLevelCDPClient.src/native-automation/isolated-window.ts: page-level native automation for the isolated target without the request pipeline;src/native-automation/index.ts: the main window ignores targets from other browser contexts.src/test-run/isolated-session.ts: command execution over CDP, selector and client function evaluation, assertions, iframe contexts, dialogs, cookies, screenshots; remote objects live in CDP object groups released when the last command in flight finishes.src/api/test-controller/isolated.js:IsolatedTestControlleron thedelegatedAPIpattern with its own command chain;t2.run.src/test-run/index.ts,src/api/test-controller/index.js:openIsolatedSessiontask and session disposal in_done.src/errors: E103isolatedSessionRequiresNativeAutomationError.ts-defs-src:IsolatedTestControllerandopenIsolatedSessiondefinitions.Tests
test/functional/fixtures/isolated-sessions/: 88 tests (basic isolation 7, commands 19, actions 19, selector chaining 10,t2.run11, iframes 9, cookies 5, screenshots 2, file upload 1, HTTP auth 1, roles 1, window management 3, native dialogs and navigation errors in the commands and actions fixtures). Gulp tasktest-functional-local-isolated-sessions.test/server/isolated-context-test.js: 4 tests for context creation and disposal, disposal on attach failure, one shared browser connection, reconnect after disconnect.test/server/isolated-session-test.js: 5 tests for remote-object release (command object group released after success, failure and overlapping commands; iframe handles kept untilswitchToMainWindow, released on navigation).test/server/data/test-suites/typescript-defs/isolated-sessions.tsand theTestControllerdefinitions check incompiler-test.js.test/server/test-run-error-formatting-test.js: E103.Verified locally with Chrome 154 headless, native automation: functional 88/88, server tests above,
gulp lintclean.Notes
The feature is in daily use in our multi-user e2e suite; the code was reviewed and reworked (element resolution, auto-wait, iframes, dialogs, leaks,
t2.runrouting) before this update. Happy to split the PR (CDP context creation first, controller second) or change the API shape if that helps review.